#include "../../include/MenuHandler.hpp"

// 构造函数初始化基类ApiHandler
MenuHandler::MenuHandler(DatabasePool& pool) : ApiHandler(pool) {
	std::cout << "[DEBUG] Handler构造 @" << this 
              << " 线程ID: " << std::this_thread::get_id() << std::endl;
	assert(dynamic_cast<ApiHandler*>(this));
}

// 获取分类信息
void MenuHandler::getCategories([[maybe_unused]] const Request& req, Response& res) {
	try {
		// 使用事务处理数据库操作
        withTransaction([&](DBUtil::Transaction& trans) {
			// SQL查询获取所有菜品分类
			Value categrories = trans.query("SELECT id, name, description, image_url FROM categories ORDER BY name");
			// 成功就响应 分类信息是 JSON 格式
			sendSucess(res, categrories);		 // 确保res在事务提交前有效
		});
	} catch (const exception& e) {
		sendError(res, e.what());		// 异常时res仍有效
	}
}

// 陈列菜品列表 根据查询输入参数来筛选
void MenuHandler::getDishes(const Request& req, Response& res) {
	try {
		// 从请求参数中获取"available"（是否仅获取可用菜品）和"category_id"（分类ID）
		bool availableOnly = true;
		auto it = req.params.find("available");
		if (it != req.params.end()) {
			availableOnly = (it->second == "1" || it->second == "true");
		}
		int categoryId = 0;
		auto catIt = req.params.find("category_id");
		if (catIt != req.params.end()) {
			try {
				categoryId = std::stoi(catIt->second);
			} catch (...) {
				categoryId = 0;
			}
		}
		// 使用事务处理数据库操作
        withTransaction([&](DBUtil::Transaction& trans) {
			// 构造SQL查询，获取菜品和其对应的分类信息
			string sql = "SELECT d.id, d.name, d.description, d.price, "
                        "d.image_url, d.stock, c.name as category_name "
                        "FROM dishes d LEFT JOIN categories c ON d.category_id = c.id "
                        "WHERE 1=1 ";
			// 传入参数不同 查询条件不同
			if (availableOnly) sql += " AND d.is_available = TRUE ";  // 仅获取可用菜品
			if (categoryId > 0) sql += " AND d.category_id = " + to_string(categoryId);		// 根据分类Id来过滤查询条件
			sql += " ORDER BY d.name";	// 普遍情况就是按照菜品名来排序
			// get 结果集
			Value dishes = trans.query(sql);
			// sucess 格式是JSON的
			sendSucess(res, dishes);
		});
	} catch (const exception& e) {
		sendError(res, e.what());
	}
}
// 更新菜品库存
void MenuHandler::updateDishStock(const Request& req, Response& res) {
	try {
		// 在更新之前要先解析原本的 得到原本的条件才能更新
		Value params = parseRequest(req);
		// 检测参数是否完整 缺少参数给错误响应
		if (!validateParams(params, {"dish_id", "quantity"})) 
			return sendError(res, "需要传入 菜品ID 和 数量", 400);
		// 使用事务处理数据库操作
        withTransaction([&](DBUtil::Transaction& trans) {
			string sql = "UPDATE dishes SET stock = stock + " + to_string(params["quantity"].asInt()) + " WHERE id = " + to_string(params["dish_id"].asInt());
			// 更新操作
			int affected = trans.execute(sql);		// 非查询方法就调用execute
			// 没有记录更新 代表菜品不存在 throw
			if (affected == 0)  	throw runtime_error("菜品不存在");
			// 不进错误警告就是 正常 成功响应
			Value response;
			response["message"] = "库存更新成功";
			sendSucess(res, response);
		});
	} catch (const exception& e) {
		sendError(res, e.what());
	}
}
// 获取菜品详情，提供单个菜品的详细信息
void MenuHandler::getDishDetails(const Request& req, Response& res) {
	try {
		// 从请求中获取菜品ID，并验证其有效性
		int dishId = 0;
		auto dishIt = req.params.find("dish_id");
		if (dishIt != req.params.end()) {
			try {
				dishId = std::stoi(dishIt->second);
			} catch (...) {
				dishId = 0;
			}
		}
		// 无效就 给错误响应
		if (dishId <= 0) 	return sendError(res, "无效的菜品ID", 400);
		withTransaction([&](DBUtil::Transaction& trans) {
			// 构造SQL查询语句，获取指定菜品的详细信息
            string sql = "SELECT d.*, c.name as category_name FROM dishes d "
                        "LEFT JOIN categories c ON d.category_id = c.id "
                        "WHERE d.id = " + to_string(dishId);
			// 给结果集
			Value ans = trans.query(sql);
			if (ans.empty() || !ans.isArray() || ans.size() == 0)	throw runtime_error("菜品不存在");
			// 成功就sendSucess
			sendSucess(res, ans[0]);
		});
	} catch (const exception& e) {
		sendError(res, e.what());
	}
}
// 添加新菜品，提供一个API来创建新的菜品
void MenuHandler::addDish(const Request& req, Response& res) {
	try {
		// 解析请求 菜品基本信息
		Value params = parseRequest(req);
		// vector 传可变参数 菜品名称 价格 分类ID
		vector<string> required = {"name", "price", "category_id"};
		if (!validateParams(params, required)) 	return sendError(res, "缺少必要参数", 400);
		withTransaction([&](DBUtil::Transaction& trans) {
			// 加菜品就是插入语句
			string sql = "INSERT INTO dishes (name, description, price, "
                        "image_url, stock, is_available, category_id) VALUES ('" +
                        params["name"].asString() + "', '" +
                        getStringParam(params, "description", "") + "', " +
                        to_string(params["price"].asDouble()) + ", '" +
                        getStringParam(params, "image_url", "") + "', " +
                        to_string(getIntParam(params, "stock", 0)) + ", " +
                        (getIntParam(params, "is_available", 1) ? "TRUE" : "FALSE") + ", " +
                        to_string(params["category_id"].asInt()) + ")";
			// 根据构造的语句进行 插入
			int affected = trans.execute(sql);
			if (affected <= 0) 	// 没有记录 就代表插入失败 抛异常
				throw runtime_error("添加菜品失败");
			// 插入操作成功  201
			Value response;
			response["message"] = "菜品添加成功";
			sendSucess(res, response, 201);
		});
	} catch (const exception& e) {
		sendError(res, e.what());
	}
}

MenuHandler::~MenuHandler() = default;